#pragma once


#include <memory>
#include "Containers/Containers.h"

#include "ScriptCompiler/Description/IdentifierDescription.h"
#include "ScriptRuntime/Type/ConstantValue.h"
#include "DecoratedTypeDescription.h"

class CDecoratorDescription;
class CExpressionNode;
class CTypeDescription;

class CConstantValueSource;

class CGSharpFieldDescription : public IIdentifierDescription
{
public:
    virtual EIdentifierType GetIdentifierType() const override
    {
        return EIdentifierType::Field;
    }

    std::weak_ptr<CTypeDescription> ParentClass;

    //static field and non-static field is not in same array
    //Native class field index is set in derivation stage
    //Script class field index is set in generate bytecode stage
    //because some native class field is not in script class
    //so the index is not continuous
    int32_t FieldIndex=-1;

    TVector<CString> ParentScopeNameChain;
    CString Name;

    SDecoratedTypeDescription Type;

    std::shared_ptr<CDecoratorDescription> Decorator;
    
    //expression to initialize non-constant field in compile time
    //the expression might be constant
    std::shared_ptr<CExpressionNode> NonConstInitializer;

    //expression to initialize constant field in compile time
    //only used by Enum field now
    std::shared_ptr<CExpressionNode> ConstInitializer;
    //evaluted constant value of the constant field
    TOptional<CConstantValue> ConstValue;

    bool IsStatic() const;
    bool IsConstant() const;

    virtual CString GetSearchName() const override
    {
        return Name;
    }
};